package com.zjw.server.socket;

import com.zjw.model.enums.ClientType;
import com.zjw.server.exception.WebSocketException;
import com.zjw.server.utils.SpringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.util.WebAppRootListener;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.Map;

@ServerEndpoint("/websocket/{groupId}")
@Component
public class WebSocketServerEndpoint implements ServletContextInitializer {

    private final static Logger log = LoggerFactory.getLogger(WebSocketServerEndpoint.class);

    private String groupId;
    private String userId;
    private ClientType clientType;

    private Session session;

    private SessionContainer sessionContainer;

    public WebSocketServerEndpoint() {
        log.info("--------WebSocketServer创建--------");
    }

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(@PathParam("groupId") String groupId, Session session) throws IOException {
        paramToField(groupId, session);
        sessionContainer = SpringUtils.getBean(SessionContainer.class);
        sessionContainer.addSession(groupId, userId, clientType, session);
        log.info("onOpen: 用户: " + userId + " 已上线！");
    }

    private void paramToField(String groupId, Session session) {
        if (StringUtils.isBlank(groupId)) {
            throw new WebSocketException("groupId is empty");
        }
        this.groupId = groupId;
        this.session = session;
        Map<String, List<String>> requestParameterMap = session.getRequestParameterMap();
        List<String> userIds = requestParameterMap.get("userId");
        if (CollectionUtils.isEmpty(userIds)) {
            throw new WebSocketException("userId is empty");
        }
        this.userId = userIds.get(0);
        List<String> clientTypes = requestParameterMap.get("clientType");
        if (CollectionUtils.isEmpty(clientTypes)) {
            throw new WebSocketException("clientType is empty");
        }
        this.clientType = ClientType.valueOf(clientTypes.get(0));
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("onMessage: " + message);
    }

    /**
     * 该方法用于接收字节流数组
     *
     * @param message 文件字节流数组
     * @param session 会话
     */
    @OnMessage
    public void onMessage(byte[] message, Session session) {
        log.info("onMessage byte: " + message.length);
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session) throws IOException {
        sessionContainer.removeSession(groupId, userId, clientType);
    }

    /**
     * 发生错误时调用
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("用户：" + userId + "发生错误");
        sessionContainer.removeSession(groupId, userId, clientType);
    }

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        servletContext.addListener(WebAppRootListener.class);
        //配置websocket传输大小，10k
        servletContext.setInitParameter("org.apache.tomcat.websocket.textBufferSize", "10240");
        servletContext.setInitParameter("org.apache.tomcat.websocket.binaryBufferSize", "10240");
    }
}
